package com.lyz.myself.controller.login;

import com.lyz.myself.config.exception.CustomException;
import com.lyz.myself.config.exception.CustomUnauthorizedException;
import com.lyz.myself.config.utils.JedisUtil;
import com.lyz.myself.config.utils.JwtUtil;
import com.lyz.myself.config.utils.base.CodeMsg;
import com.lyz.myself.config.utils.Result;
import com.lyz.myself.controller.BaseController;
import com.lyz.myself.pojo.Po.User;
import com.lyz.myself.pojo.Po.common.Constant;
import com.lyz.myself.pojo.Po.common.ResponseBean;
import com.lyz.myself.pojo.Vo.PositionVo;
import com.lyz.myself.pojo.Vo.UserLoginVo;
import com.lyz.myself.pojo.Vo.UserVo;
import com.lyz.myself.service.PositionService;
import com.lyz.myself.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

import static com.lyz.myself.config.utils.util.MD5Util.commonMD5;


@Api(description="登录模块")
@RestController
@PropertySource("classpath:config.properties")
public class LoginController extends BaseController {
    @Autowired
    private UserService userService;

    @Autowired
    private PositionService positionService;
    /**
     * RefreshToken过期时间
     */
    @Value("${refreshTokenExpireTime}")
    private String refreshTokenExpireTime;

    @ApiOperation(value="获取在线用户(查询Redis中的RefreshToken)")
    @GetMapping("/online")
    @RequiresRoles(logical = Logical.OR,value = {"admin"})
    public Result online() {
        List<Object> userDtos = new ArrayList<Object>();
        // 查询所有Redis键
        Set<String> keys = JedisUtil.keysS(Constant.PREFIX_SHIRO_REFRESH_TOKEN + "*");
        for (String key : keys) {
            if (JedisUtil.exists(key)) {
                // 根据:分割key，获取最后一个字符(帐号)
                String[] strArray = key.split(":");
                Map<String,Object> map = new HashMap();
                map.put("name",strArray[strArray.length - 1]);
                // 设置登录时间
                map.put("logingTme",new Date(Long.parseLong(JedisUtil.getObject(key).toString())));
                userDtos.add(map);
            }
        }
        if (userDtos == null || userDtos.size() <= 0) {
            throw new CustomException("查询失败");
        }
        return Result.success(userDtos,"查询成功");
    }

    @ApiOperation(value="测试登录")
    @RequiresAuthentication
    @RequestMapping(value = "/article",method = RequestMethod.GET)
    public ResponseBean article() {
        Subject subject = SecurityUtils.getSubject();
        // 登录了返回true
        if (subject.isAuthenticated()) {
            return new ResponseBean(HttpStatus.OK.value(), "您已经登录了", JwtUtil.getUserId());
        } else {
            return new ResponseBean(HttpStatus.OK.value(), "你是游客", JwtUtil.getUserId());
        }
    }

    @ApiOperation(value="登录",notes="用户名，密码")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType="query", name = "userName", value = "用户名", required = true, dataType = "String"),
            @ApiImplicitParam(paramType="query", name = "password", value = "密码", required = true, dataType = "String"),
            @ApiImplicitParam(paramType="query", name = "rememberMe", value = "是否记住我", required = false, dataType = "boolean"),
            @ApiImplicitParam(paramType="query", name = "compamy_id", value = "公司id",required = true,dataType = "Integer")
    })
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public Result login(@RequestParam(value = "userName") String userName,
                        @RequestParam(value = "password")String password,
                        @RequestParam(value = "rememberMe",required = false,defaultValue = "true")boolean rememberMe,
                        @RequestParam(value = "compamy_id")Integer compamy_id,
                        HttpServletResponse httpServletResponse) {
        //校验验证码
        //session中的验证码
//        String sessionCaptcha = (String) SecurityUtils.getSubject().getSession().getAttribute(CaptchaController.KEY_CAPTCHA);
//        if (null == captcha || !captcha.equalsIgnoreCase(sessionCaptcha)) {
//            return Result.error(CodeMsg.ERROR,"验证码错误！");
//        }
        User user = userService.getUserByCompany(userName,compamy_id);

        if (user == null) {
            throw new CustomUnauthorizedException("该帐号不存在");
        }
        UserLoginVo userVo = ejbGenerator.convert(user, UserLoginVo.class);
        String userType =  positionService.getDescription(user.getUser_id());
        if(userType!=null){
            if(userType.equals("admin")){
                userVo.setUserType("超级管理员");
            }else if(userType.equals("CEO")){
                userVo.setUserType("CEO");
            }else if(userType.equals("companyAdmin")){
                userVo.setUserType("机构管理员");
            }else{
                userVo.setUserType("普通员工");
            }
        }else{
            userVo.setUserType("游客");
        }
//        String key = new SimpleHash("MD5", password,user.getSalt(), 2).toHex();
        String key = commonMD5(commonMD5(password)+user.getSalt());

        if (key.equals(user.getPassword())) {
            // 清除可能存在的Shiro权限信息缓存
            if (JedisUtil.exists(Constant.PREFIX_SHIRO_CACHE + user.getUser_id())) {
                JedisUtil.delKey(Constant.PREFIX_SHIRO_CACHE + user.getUser_id());
            }
            // 设置RefreshToken，时间戳为当前时间戳，直接设置即可(不用先删后设，会覆盖已有的RefreshToken)
            String currentTimeMillis = String.valueOf(System.currentTimeMillis());
            JedisUtil.setObject(Constant.PREFIX_SHIRO_REFRESH_TOKEN +user.getUser_id()+"", currentTimeMillis, Integer.parseInt(refreshTokenExpireTime));
            // 从Header中Authorization返回AccessToken，时间戳为当前时间戳
            String token = JwtUtil.sign(user.getUser_id()+"", currentTimeMillis);
            httpServletResponse.setHeader("Authorization", token);
            httpServletResponse.setHeader("Access-Control-Expose-Headers", "Authorization");
            return Result.success(userVo,"登录成功！");
        } else {
            throw new CustomUnauthorizedException("帐号或密码错误");
        }
    }


    @ApiOperation(value="测试登录注解(@RequiresAuthentication和subject.isAuthenticated()返回true一个性质)")
    @GetMapping("/article2")
    @RequiresAuthentication
    public Result requireAuth() {
        return Result.success("您已经登录了");
    }

    @ApiOperation(value="退出")
    @GetMapping("/signOut")
    public Result signOut() {
        org.apache.shiro.subject.Subject subject = SecurityUtils.getSubject();
        //自己手动退出删除redis限制人数key 防止sessionId null异常
        String userId = JwtUtil.getClaim(subject.getPrincipal().toString(), Constant.NAME);
        if (JedisUtil.exists(Constant.PREFIX_SHIRO_REFRESH_TOKEN + userId)) {
            if (JedisUtil.delKey(Constant.PREFIX_SHIRO_REFRESH_TOKEN + userId) > 0) {
                return Result.success("退出成功");
            }
        }
        return Result.error(CodeMsg.ERROR,"退出失败");
    }
}
